require("Middleclass")
require("Invoker")
require("GetterSetter")
require("Branchy")
require("Callbacks")
require("Apply")
require("Beholder")
require("Stateful")
require("Indexable")
require("Strict")
require("Debug")
require("Logger")
require("Random")

require("Field")
require("Society")
require("World")
require("Cast")
require("Player")
require("Bot")
require("DramaManager")
require("StageParser")
require("GraphmlStageParser")
require("CastParser")

Game = class("Game")

---

function Game:initialize(stage, cast)

	gGame = self
	
	Logger:new()
	Random:new()
	
	Field:new()
	
	gLogger:enterGroup("Parste Stage and Cast")
	
	if type(stage) == "table" 
	then
		StageParser:new(stage)
	else
		GraphmlStageParser:new(stage)
	end
	
	CastParser:new(cast)
	
	-- we don'y leave the log group here because it will be done in the onBeat function
		
	Player:new(gField.entityTypes.Location[cast.Player.initialLocation])
	DramaManager:new()
end

---

function Game:start()

	self:onBeat()
end

---

function Game:onBeat()

	gMonitor:onBeatStart()


	-- increase beat counter
	
	gField.beat = gField.beat + 1
	
	gLogger:leaveGroup()							-- we leave the previous beat group. For the first beat, this close the log group openened in the initialize function
	gLogger:enterGroup("Beat " .. gField.beat)	
	
	-- update drama manger and field
	
	gDramaManager:onBeatBeforeField()
	gField:onBeat()
	gDramaManager:onBeatAfterField()
	
	gMonitor:onBeatEnd()

	
	-- update view
	
	if gView then
	
		gView:update()
	end

	
	-- we dont leave log group here, we do it after the player actions
	
end